// Package car_park_api
// @Author Spume
// @Date 2024-12-19

package car_park_api

import (
	"context"
	"net/url"

	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

// CarParkService 停车场服务接口
type CarParkService interface {
	// 停车场管理
	GetParks(ctx context.Context, input *GetParksInput) ([]*ParkSimple, error)

	// 月卡管理
	GetMonthCars(ctx context.Context, input *GetMonthCarsInput) (*GetMonthCarsResponse, error)

	// 订单管理
	GetOrders(ctx context.Context, input *GetOrdersInput) ([]*ParkBusiness, error)
	GetAbnormalOrders(ctx context.Context, input *GetAbnormalOrdersInput) ([]*AbnormalOrder, error)
}

// carParkServiceImpl 停车场服务实现
type carParkServiceImpl struct {
	host string // API主机地址
}

// NewCarParkService 创建停车场服务实例
func NewCarParkService(host ...string) CarParkService {
	apiHost := DefaultParkHost
	if len(host) > 0 && host[0] != "" {
		apiHost = host[0]
	}
	return &carParkServiceImpl{
		host: apiHost,
	}
}

// GetParks 获取停车场列表
func (s *carParkServiceImpl) GetParks(ctx context.Context, input *GetParksInput) ([]*ParkSimple, error) {
	if err := input.IsValid(); err != nil {
		return nil, err
	}

	// 构建签名参数
	m := url.Values{}
	m.Add("AC", input.AK)
	m.Add("Key", input.SK)
	m.Add("PageIndex", gconv.String(input.Page))
	m.Add("PageSize", gconv.String(input.Limit))
	m.Add("CompanyCode", input.CompanyCode)

	// 发送请求
	res, err := g.Client().Discovery(nil).ContentJson().Post(
		ctx,
		s.host+GetParksAPI,
		g.Map{
			"AC":          input.AK,
			"PageIndex":   input.Page,
			"PageSize":    input.Limit,
			"CompanyCode": input.CompanyCode,
			"Sign":        gmd5.MustEncryptString(m.Encode()),
		},
	)
	if err != nil {
		return nil, NewNetworkError("请求停车场列表失败", err)
	}

	if input.Debug {
		res.RawDump()
	}

	// 解析响应
	var response CommonResponse[GetParksResponse]
	err = gjson.Unmarshal(res.ReadAll(), &response)
	if err != nil {
		return nil, NewParseError("解析停车场列表响应失败", err)
	}

	if response.Status != StatusSuccess {
		return nil, NewAPIError(response.Status, response.Msg, nil)
	}

	return response.Data.Data, nil
}

// GetMonthCars 获取月卡用户列表
func (s *carParkServiceImpl) GetMonthCars(ctx context.Context, input *GetMonthCarsInput) (*GetMonthCarsResponse, error) {
	if err := input.IsValid(); err != nil {
		return nil, err
	}

	// 构建签名参数
	m := url.Values{}
	m.Add("AC", input.AK)
	m.Add("Key", input.SK)
	m.Add("ParkCodes", gconv.String(input.ParkCodes))
	m.Add("CarNumber", input.CarNumber)
	m.Add("PageIndex", gconv.String(input.PageIndex))
	m.Add("PageSize", gconv.String(input.PageSize))

	// 发送请求
	res, err := g.Client().Discovery(nil).ContentJson().Post(
		ctx,
		s.host+GetMonthCarAPI,
		g.Map{
			"AC":        input.AK,
			"ParkCodes": input.ParkCodes,
			"CarNumber": input.CarNumber,
			"PageIndex": input.PageIndex,
			"PageSize":  input.PageSize,
			"Sign":      gmd5.MustEncryptString(m.Encode()),
		},
	)
	if err != nil {
		return nil, NewNetworkError("请求月卡列表失败", err)
	}

	if input.Debug {
		res.RawDump()
	}

	// 解析响应
	var response CommonResponse[GetMonthCarsResponse]
	err = gjson.Unmarshal(res.ReadAll(), &response)
	if err != nil {
		return nil, NewParseError("解析月卡列表响应失败", err)
	}

	if response.Status != StatusSuccess {
		return nil, NewAPIError(response.Status, response.Msg, nil)
	}

	return &response.Data, nil
}

// GetOrders 获取临停订单列表
func (s *carParkServiceImpl) GetOrders(ctx context.Context, input *GetOrdersInput) ([]*ParkBusiness, error) {
	if err := input.IsValid(); err != nil {
		return nil, err
	}

	// 构建签名参数
	m := url.Values{}
	m.Add("AC", input.AK)
	m.Add("Key", input.SK)
	m.Add("ParkCode", input.ParkCode)
	m.Add("StartTime", gconv.String(input.StartTime))
	m.Add("EndTime", gconv.String(input.EndTime))

	// 发送请求
	res, err := g.Client().Discovery(nil).ContentJson().Post(
		ctx,
		s.host+GetOrdersAPI,
		g.Map{
			"AC":        input.AK,
			"ParkCode":  input.ParkCode,
			"StartTime": input.StartTime,
			"EndTime":   input.EndTime,
			"Sign":      gmd5.MustEncryptString(m.Encode()),
		},
	)
	if err != nil {
		return nil, NewNetworkError("请求订单列表失败", err)
	}

	if input.Debug {
		res.RawDump()
	}

	// 解析响应
	var response CommonResponse[[]*ParkBusiness]
	err = gjson.Unmarshal(res.ReadAll(), &response)
	if err != nil {
		return nil, NewParseError("解析订单列表响应失败", err)
	}

	if response.Status != StatusSuccess {
		return nil, NewAPIError(response.Status, response.Msg, nil)
	}

	if response.Data == nil {
		return []*ParkBusiness{}, nil
	}

	return response.Data, nil
}

// GetAbnormalOrders 获取异常订单列表
func (s *carParkServiceImpl) GetAbnormalOrders(ctx context.Context, input *GetAbnormalOrdersInput) ([]*AbnormalOrder, error) {
	if err := input.IsValid(); err != nil {
		return nil, err
	}

	// 构建签名参数
	m := url.Values{}
	m.Add("AC", input.AK)
	m.Add("Key", input.SK)
	m.Add("ThirdOrderCode", gconv.String(input.Orders))

	// 发送请求
	res, err := g.Client().Discovery(nil).ContentJson().Post(
		ctx,
		s.host+GetAbnormalOrderAPI,
		g.Map{
			"AC":             input.AK,
			"ThirdOrderCode": input.Orders,
			"Sign":           gmd5.MustEncryptString(m.Encode()),
		},
	)
	if err != nil {
		return nil, NewNetworkError("请求异常订单列表失败", err)
	}

	if input.Debug {
		res.RawDump()
	}

	// 解析响应
	var response CommonResponse[[]*AbnormalOrder]
	err = gjson.Unmarshal(res.ReadAll(), &response)
	if err != nil {
		return nil, NewParseError("解析异常订单列表响应失败", err)
	}

	if response.Status != StatusSuccess {
		return nil, NewAPIError(response.Status, response.Msg, nil)
	}

	if response.Data == nil {
		return []*AbnormalOrder{}, nil
	}

	return response.Data, nil
}
